package com.ruoyi.common.utils;

import cn.hutool.core.collection.CollUtil;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @description: List工具类
 * @author: duanyashu
 * @time: 2021-07-06 15:36
 */
public class ListUtil extends cn.hutool.core.collection.ListUtil {

    /**
     * list随机排序
     * @param list
     * @param <T>
     * @return
     */
    public static <T> List<T> sortByRandom(List<T> list) {
        List<T> newList = empty();
        int[] randoms = RandomUtils.getRandoms(0, list.size()-1, list.size());
        for (int random : randoms) {
            newList.add(list.get(random));
        }
        return newList;
    }

    /**
     * 获取list中存放的最后一个元素
     * @param list
     * @param <T>
     * @return
     */
    public static <T> T getLast(List<T> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(list.size() - 1);
    }

    /**
     * list转map I V K 分别代表输入集合泛型的类型、map中key的类型、map中值的类型
     * @param list : 输入的集合
     * @param functionK : 键转换函数
     * @param functionV : 值转换函数
     * @param mergeFuncion : key重复 value合并的函数
     * @return java.util.Map<K,V>
     */
    public static  <I,K,V> Map<K,V> list2map(Collection<I> list, Function<I,K> functionK, Function<I,V> functionV, BinaryOperator<V> mergeFuncion){
        if (list == null || list.size()==0){
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(functionK, functionV,mergeFuncion));
    }
    public static  <I,K,V> Map<K,V> list2map(I [] list, Function<I,K> functionK, Function<I,V> functionV, BinaryOperator<V> mergeFuncion){
        if (list == null || list.length ==0){
            return new HashMap<>();
        }
        return list2map(CollUtil.toList(list),functionK,functionV,mergeFuncion);
    }
    public static  <I,K,V> Map<K,V> list2map(Collection<I> list, Function<I,K> functionK, Function<I,V> functionV){
        if (list == null || list.size()==0){
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(functionK, functionV));
    }
    public static  <I,K,V> Map<K,V> list2map(I [] list, Function<I,K> functionK, Function<I,V> functionV){
        if (list == null || list.length ==0){
            return new HashMap<>();
        }
        return list2map(CollUtil.toList(list),functionK,functionV);
    }

    /**
     *
     * @param list : 输入的集合
     * @param functionO : 集合转换函数
     * @return java.util.List<O>
     */
    public static <I,O> List<O> list2list(Collection<I> list, Function<I,O> functionO){
        if (list == null || list.size()==0){
            return new ArrayList<>();
        }
        return list.stream().map(functionO).collect(Collectors.toList());
    }
    public static <I,O> List<O> list2list(I [] arr, Function<I,O> functionO){
        if (arr == null || arr.length ==0){
            return new ArrayList<>();
        }
        return list2list(toList(arr),functionO);
    }

    /**
     * list条件过滤
     * @param list : 输入的集合
     * @param predicateF : 过滤条件函数
     * @return java.util.List<I>
     */
    public static <I> List<I> listFilter(Collection<I> list, Predicate<I> predicateF){
        if (list == null || list.size()==0){
            return new ArrayList<>();
        }
        return list.stream().filter(predicateF).collect(Collectors.toList());
    }
    public static <I> List<I> listFilter(I[] list, Predicate<I> predicateF){
        if (list == null || list.length==0){
            return new ArrayList<>();
        }
        return listFilter(toList(list),predicateF);
    }
    /**
     * list条件过滤 + 输出的集合
     * @param list : 输入的集合
     * @param filter : 过滤条件函数
     * @param map : 过滤条件函数
     * @return java.util.List<I>
     */
    public static <I,O> List<O> listFilter2List(Collection<I> list, Predicate<I> filter,Function<I,O> map){
        if (list == null || list.size()==0){
            return new ArrayList<>();
        }
        return list.stream().filter(filter).map(map).collect(Collectors.toList());
    }
    public static <I,O> List<O> listFilter2List(I[] list, Predicate<I> filter,Function<I,O> map){
        if (list == null || list.length==0){
            return new ArrayList<>();
        }
        return listFilter2List(toList(list),filter,map);
    }

}
